package com.amumu.drama.common.utils.http;


import com.amumu.drama.common.utils.json.JsonObjectUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.io.IOException;
import java.util.Map;

/**
 * @author sunzhuang
 * @date 2023/2/1 13:16
 * @slogan You build it , You run it.
 */
public class HttpUtils {

    private static final CloseableHttpClient HTTP_CLIENT = HttpClientUtils.createHttpClient();

    private static Logger log = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * 处理get请求
     */
    public static CloseableHttpResponse doGetToResponse(String url, Map<String, String> headers) throws IOException {
        HttpGet httpGet = new HttpGet(url);
        if (!ObjectUtils.isEmpty(headers)) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.addHeader(entry.getKey(), entry.getValue());
            }
        }
        return HTTP_CLIENT.execute(httpGet);
    }

    public static String doGet(String url) {
        return null;
    }

    public static String doGet(String url, boolean ignoreError) {
        return null;
    }

    public static String doGet(String url, Map<String, String> params) {
        return null;
    }

    public static String doGet(String url, Map<String, String> params, boolean ignoreError) {
        return null;
    }

    public static <T> T doGet(String url, Map<String, String> params, Class<T> T) {
        return null;
    }

    public static <T> T doGet(String url, Map<String, String> params, Class<T> T, boolean ignoreError) {
        return null;
    }

    public static String doPost(String url, String param) {
        return null;
    }

    public static String doPost(String url, String param, boolean ignoreError) {
        return doPost(url, null, ContentType.APPLICATION_JSON, JsonObjectUtils.parseJsonFormObject(param), String.class, false);
    }

    public static <T> T doPost(String url, String param, Class<T> T) {
        return doPost(url, null, ContentType.APPLICATION_JSON, JsonObjectUtils.parseJsonFormObject(param), T, false);
    }

    public static <T> T doPost(String url, Object param, Class<T> T) {
        return doPost(url, JsonObjectUtils.createJson(param), T, false);
    }

    public static <T> T doPost(String url, Object param, Class<T> T, boolean ignoreError) {
        return doPost(url, JsonObjectUtils.createJson(param), T, ignoreError);
    }


    public static <T> T doPost(String url, Map<String, String> headers, Object param, Class<T> T) {
        return doPost(url, headers, ContentType.APPLICATION_JSON, JsonObjectUtils.parseJsonFormObject(param), T, false);
    }

    public static <T> T doPost(String url, Map<String, String> headers, ContentType contentType, Object param, Class<T> t) {
        return doPost(url, headers, contentType, param, t, false);
    }

    public static <T> T doPost(String url, String param, Class<T> T, boolean ignoreError) {
        return doPost(url, null, ContentType.APPLICATION_JSON, JsonObjectUtils.parseJson(param), T, ignoreError);
    }

    public static <T> T doPost(String url, Map<String, String> headers, ContentType contentType, Object params, Class<T> T, boolean ignoreError) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(3000)
                .setSocketTimeout(3000)
                .setConnectTimeout(1000)
                .build();
        try {
            HttpPost request = new HttpPost(url);
            request.setConfig(requestConfig);
            if (!ObjectUtils.isEmpty(params)) {
                if (ContentType.APPLICATION_JSON.equals(contentType)) {
                    request.setEntity(new StringEntity(JsonObjectUtils.createJson(params), ContentType.APPLICATION_JSON));
                } else if (ContentType.MULTIPART_FORM_DATA.equals(contentType) || params instanceof Map) {
                    Map<String, Object> map = BeanMapUtils.beanToMap(params);
                    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        String key = entry.getKey();
                        Object value = entry.getValue();
                        if (value instanceof String || value instanceof Integer) {
                            builder.addTextBody(key, String.valueOf(value));
                        } else if (value instanceof File) {
                            builder.addBinaryBody(key, (File) value);
                        }
                    }
                    request.setEntity(builder.build());
                }
            }
            if (!ObjectUtils.isEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    request.addHeader(entry.getKey(), entry.getValue());
                }
            }
            try (CloseableHttpResponse response = HTTP_CLIENT.execute(request)) {
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    String respContent = EntityUtils.toString(response.getEntity());
                    log.info("HttpUtils: success response={}", respContent);
                    return JsonObjectUtils.parseJson(respContent, T);
                }
                String respContent = EntityUtils.toString(response.getEntity());
                log.warn("HttpUtils: fail response={}", respContent);
                return JsonObjectUtils.parseJson(respContent, T);
            }
        } catch (
                IOException e) {
            if (ignoreError) {
                log.error("LogNotifier: sendNotify error", e);
                return null;
            }
            throw new RuntimeException(e);
        }
    }

}
